﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ValidationFramework
{
	public class MethodPolicy
	{
		IValidationPolicyFactory _vpFactory;

        // --- Constructors

		internal MethodPolicy(IValidationPolicyFactory vpFactory)
        {
			_vpFactory = vpFactory;

			ParameterPolicyDictionary = new Dictionary<ParameterKey, IValidationPolicy>();
        }

        // --- Properties

		public Dictionary<ParameterKey, IValidationPolicy> ParameterPolicyDictionary
        {
            get;
            private set;
        }

		public int RuleCount
		{
			get
			{
				return ParameterPolicyDictionary.Sum(x => x.Value.RuleCount);
			}
		}

		// --- Methods | Validation Policys

		/// <summary>
		/// Adds a rule to the validation policy at the given property key
		/// </summary>
		/// <param name="key"></param>
		/// <param name="rule"></param>
		/// <param name="scope"></param>
		/// <remarks>If a descriptor with the given key doesn't exist one will be created</remarks>
		public IValidationPolicy GetOrCreateParameterPolicy(ParameterKey key)
		{
			IValidationPolicy policy;
			if (!ParameterPolicyDictionary.TryGetValue(key, out policy))
			{
				// create and add one
				var newPolicy = _vpFactory.CreateParameterValidationPolicy(key);
				ParameterPolicyDictionary.Add(key, newPolicy);
				return newPolicy;
			}
			else
				return policy;
		}


		public IList<ValidationError> Validate(MethodCall methodCall, ValidationOptions options)
		{
			// validate each policy saving errors to the errorlist
			var errors = new List<ValidationError>();

			foreach (var kvp in ParameterPolicyDictionary)
			{
				var policy = kvp.Value;

				errors.AddRange(policy.Validate(methodCall, options));
			}

			return errors;
		}


		public void RemoveParameterPolicy(ParameterKey key)
		{
			ParameterPolicyDictionary.Remove(key);
		}
	}
}
